package cn.wangliang181230.boot.web.environmentpostprocessor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class MyConfigCenterEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {

	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
		System.out.println(this.getClass().getSimpleName() + " : " + environment.getClass().getSimpleName());
		System.out.println("从配置中心读取配置：start");

		//region 读取配置中心的配置

		MyConfigCenterProperties properties = new MyConfigCenterProperties();
		Binder.get(environment).bind("my.config-center", Bindable.ofInstance(properties));

		if (!properties.isEnabled()) {
			System.out.println("未启用配置中心");
			return;
		}
		if (!StringUtils.hasLength(properties.getDataId())) {
			System.out.println("未配置配置中心data-id");
			return;
		}

		System.out.println("配置中心root地址：" + properties.getRootUrl());
		System.out.println("从配置中心加载配置：" + properties.getDataId());

		//endregion

		// 拼接api地址
		String apiUrl;
		try {
			apiUrl = properties.getRootUrl() + "/getConfig?dataId=" + URLEncoder.encode(properties.getDataId(), StandardCharsets.UTF_8.name());
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}

		// 调用接口，获取配置
		RestTemplate restTemplate = new RestTemplate();
		Map<String, Object> configData = restTemplate.getForObject(apiUrl, Map.class);
		if (configData == null) {
			configData = new HashMap<>();
		}

		// 将配置放到配置源中
		MapPropertySource mps = new MapPropertySource("from-config-center[" + properties.getDataId() + "]", configData);

		// 放入配置源列表中
		String name1 = "systemEnvironment";
		String name2 = "systemProperties";
		if (environment.getPropertySources().get(name1) != null) {
			environment.getPropertySources().addAfter(name1, mps);
		} else if (environment.getPropertySources().get(name2) != null) {
			environment.getPropertySources().addAfter(name2, mps);
		} else {
			environment.getPropertySources().addFirst(mps);
		}
	}


	@Override
	public int getOrder() {
		// 比springboot读取配置文件功能晚执行，否则配置中心的配置读取不到
		return ConfigDataEnvironmentPostProcessor.ORDER + 10;
	}

}
